home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
526-550
/
disk_535
/
icon
/
icon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
26KB
|
1,275 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by Olaf Barthel & MXM
*
* Name .....: Icon.c
* Created ..: Friday 10-May-91 16:58
* Revision .: 0
*
* Date Author Comment
* ========= ======== ====================
* 10-May-91 Olsen Created this file!
*
* $Revision Header ********************************************************/
/* A quick set of file types we are able to provide icons for. */
enum { TYPE_DIR,TYPE_FILE,TYPE_ICON,
TYPE_TEXT,
TYPE_C,TYPE_H,
TYPE_ASM,TYPE_I,
TYPE_MOD,
TYPE_REXX,
TYPE_BASIC,
TYPE_TEX,TYPE_METAFONT,TYPE_GF,TYPE_TEXFONT,TYPE_TEXDVI,TYPE_FLIB,
TYPE_OLDMANX,TYPE_NEWMANX,TYPE_OLDMANXLIB,TYPE_NEWMANXLIB,
TYPE_OBJECT,TYPE_LIB,
TYPE_EXECUTABLE,
TYPE_LIBRARY,TYPE_DEVICE,TYPE_FILESYS,TYPE_HANDLER,
TYPE_GIF,TYPE_ILBM,TYPE_ANIM,TYPE_8SVX,TYPE_SMUS,TYPE_FTXT,TYPE_PREFS,TYPE_TERM,
TYPE_IMPLODER,TYPE_POWERPACKER,
TYPE_ARC,TYPE_LHARC,TYPE_ZOO,TYPE_ZIP,TYPE_DMS,TYPE_WARP,TYPE_ZOOM,
};
/* Name of the global handshake port. */
#define PORTNAME "Icon Rendezvous"
/* Library vector offsets for a bunch of routines. */
#define EXAMINE -102
#define EXNEXT -108
#define OPEN -30
#define CLEARMENUSTRIP -54
/* This structure describes the global handshake port. */
struct IconPort
{
struct MsgPort VanillaPort;
BPTR Segment;
VOID (*Remove)();
};
/* A structure containing both a file name suffix and the
* approriate file type.
*/
struct Suffix
{
UBYTE *Name;
UBYTE Type;
};
/* A structure containing an icon file name and a special
* purpose flag.
*/
struct NameInfo
{
UBYTE *Name;
BYTE IsPresent;
};
/* A table of valid ASCII characters (7 bits). */
BYTE ValidTab[256] =
{
0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,
0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
/* A table of clearly invalid ASCII characters (8 bits). */
BYTE InvalidTab[256] =
{
1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,
1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
/* Some file name suffixes for text files and the approriate
* file types.
*/
struct Suffix TextSuffix[] =
{
".C", TYPE_C,
".CP", TYPE_C,
".CC", TYPE_C,
".H", TYPE_H,
".ASM", TYPE_ASM,
".A", TYPE_ASM,
".S", TYPE_ASM,
".I", TYPE_I,
".BAS", TYPE_BASIC,
".GFA", TYPE_BASIC,
".REXX",TYPE_REXX,
".CED", TYPE_REXX,
".VLT", TYPE_REXX,
".CPR", TYPE_REXX,
".TxEd",TYPE_REXX,
".TEX", TYPE_TEX,
".STY", TYPE_TEX,
".MF", TYPE_METAFONT,
".MOD", TYPE_MOD,
".DEF", TYPE_MOD
};
/* Some more file name suffixes for executable files and the
* approriate file types.
*/
struct Suffix ExecutableSuffix[] =
{
".device", TYPE_DEVICE,
".library", TYPE_LIBRARY,
"FileSystem", TYPE_FILESYS,
"Handler", TYPE_HANDLER
};
/* This list contains the names of all icon files which can be
* attached to the files to be identified. The flag byte indicates
* whether an icon is available or not.
*/
struct NameInfo NameInfo[] =
{
NULL, FALSE,
NULL, FALSE,
NULL, FALSE,
"text", FALSE,
"c", FALSE,
"h", FALSE,
"asm", FALSE,
"i", FALSE,
"mod", FALSE,
"rexx", FALSE,
"basic", FALSE,
"tex", FALSE,
"metafont", FALSE,
"gf", FALSE,
"pk", FALSE,
"dvi", FALSE,
"flib", FALSE,
"manx3object", FALSE,
"manx5object", FALSE,
"manx3lib", FALSE,
"manx5lib", FALSE,
"object", FALSE,
"lib", FALSE,
NULL, FALSE,
"library", FALSE,
"device", FALSE,
"filesys", FALSE,
"handler", FALSE,
"gif", FALSE,
"pic", FALSE,
"anim", FALSE,
"sound", FALSE,
"score", FALSE,
"ftxt", FALSE,
"pref", FALSE,
"term", FALSE,
"imploder", FALSE,
"powerpacker", FALSE,
"arc", FALSE,
"lharc", FALSE,
"zoo", FALSE,
"zip", FALSE,
"dms", FALSE,
"warp", FALSE,
"zoom", FALSE
};
/* Prototypes for functions in this module and Bypass.asm */
extern LONG __asm MyExamine(register __d1 BPTR FileLock,register __d2 struct FileInfoBlock *FileInfo);
LONG __saveds __asm NewExamine(register __d1 BPTR FileLock,register __d2 struct FileInfoBlock *FileInfo);
extern LONG __asm MyExNext(register __d1 BPTR FileLock,register __d2 struct FileInfoBlock *FileInfo);
LONG __saveds __asm NewExNext(register __d1 BPTR FileLock,register __d2 struct FileInfoBlock *FileInfo);
extern BPTR __asm MyOpen(register __d1 UBYTE *Name,register __d2 LONG Mode);
BPTR __saveds __asm NewOpen(register __d1 UBYTE *Name,register __d2 LONG Mode);
extern VOID __asm MyClearMenuStrip(register __a0 struct Window *Window);
VOID __saveds __asm NewClearMenuStrip(register __a0 struct Window *Window);
VOID __saveds RemoveIcon(VOID);
BYTE InstallIcon(VOID);
struct Node * MyFindName(struct List *List,UBYTE *Name);
UBYTE Local2Upper(UBYTE c);
UBYTE StrCmp(UBYTE *a,UBYTE *b);
VOID DeleteNode(struct Node *Node);
struct Node * CreateNode(UBYTE *Name);
VOID AddName(UBYTE *FileName,UBYTE Type);
ULONG __saveds Main(VOID);
/* Global and shared library identifiers. */
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct IntuitionBase *IntuitionBase;
/* Pointers to the old library routines. */
APTR OldExamine;
APTR OldExNext;
APTR OldOpen;
APTR OldClearMenuStrip;
/* The list containing the files which do not have an icon and the
* access semaphore.
*/
struct SignalSemaphore NameSemaphore;
struct List NameList;
/* The node being scanned. */
struct Node *ScanNode;
/* True if ExNext is to perform fake scanning, else false. */
BYTE FakeScan;
/* Global handshake port. */
struct IconPort *IconPort;
/* Main():
*
* Program entry point.
*/
ULONG __saveds
Main()
{
struct Process *ThisProcess;
/* Set up SysBase. */
SysBase = *(struct ExecBase **)4;
/* Look who we are. */
ThisProcess = (struct Process *)SysBase -> ThisTask;
/* Started from Shell? */
if(ThisProcess -> pr_CLI)
{
/* Open the DOS library. */
if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36))
{
Printf("\33[1m\33[33mIcon\33[31m © \33[0mCopyright 1991 by Olaf Barthel, ");
/* If the port is available remove an
* already running `Icon'.
*/
if(IconPort = (struct IconPort *)FindPort(PORTNAME))
{
Flush(ThisProcess -> pr_COS);
Printf("Removing patch... ");
Flush(ThisProcess -> pr_COS);
Forbid();
IconPort -> Remove();
Permit();
Printf("done.\n");
CloseLibrary(DOSBase);
}
else
{
/* Install `Icon'. */
Flush(ThisProcess -> pr_COS);
Printf("Installing patch... ");
Flush(ThisProcess -> pr_COS);
if(InstallIcon())
Printf("done.\n");
else
{
Printf("failed!\a\n");
CloseLibrary(DOSBase);
}
}
}
else
return(RETURN_FAIL);
}
else
{
struct Message *Message;
/* Wait for Workbench startup message. */
Message = (struct Message *)WaitPort(&ThisProcess -> pr_MsgPort);
Forbid();
/* And reply it. */
ReplyMsg(Message);
}
return(RETURN_OK);
}
/* MyFindName(struct List *List,UBYTE *Name):
*
* Find a node in a list, scan for the name ignoring
* case.
*/
struct Node *
MyFindName(struct List *List,UBYTE *Name)
{
struct Node *Node;
Node = List -> lh_Head;
while(Node -> ln_Succ)
{
if(!StrCmp(Node -> ln_Name,Name))
return(Node);
Node = Node -> ln_Succ;
}
return(NULL);
}
/* RemoveIcon():
*
* Remove a previously installed `Icon'.
*/
VOID __saveds
RemoveIcon()
{
struct Node *Node,*NextNode;
BPTR Segment;
/* Look for the port. */
IconPort = (struct IconPort *)FindPort(PORTNAME);
Segment = IconPort -> Segment;
/* Remove it. */
RemPort(&IconPort -> VanillaPort);
FreeVec(IconPort);
Node = NameList . lh_Head;
/* Delete all the nodes in the list if necessary. */
while(Node -> ln_Succ)
{
NextNode = Node -> ln_Succ;
DeleteNode(Node);
Node = NextNode;
}
/* Restore the system library vectors if possible. */
SetFunction(DOSBase, EXAMINE, OldExamine);
SetFunction(DOSBase, EXNEXT, OldExNext);
SetFunction(DOSBase, OPEN, OldOpen);
SetFunction(IntuitionBase, CLEARMENUSTRIP, OldClearMenuStrip);
/* Remove the `Icon' program. */
UnLoadSeg(Segment);
/* Close the libraries. */
CloseLibrary(IntuitionBase);
CloseLibrary(DOSBase);
}
/* InstallIcon():
*
* Install `Icon' and get it running.
*/
BYTE
InstallIcon()
{
/* Create the global port. */
if(IconPort = (struct IconPort *)AllocVec(sizeof(struct IconPort) + sizeof(PORTNAME),MEMF_PUBLIC|MEMF_CLEAR))
{
IconPort -> VanillaPort . mp_Node . ln_Name = (UBYTE *)(IconPort + 1);
strcpy(IconPort -> VanillaPort . mp_Node . ln_Name,PORTNAME);
IconPort -> VanillaPort . mp_Flags = PA_IGNORE;
/* Open Intuition. */
if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",36))
{
/* Set up the name list. */
InitSemaphore(&NameSemaphore);
NewList(&NameList);
/* Modify system functions. */
OldExamine = (APTR)SetFunction(DOSBase, EXAMINE, NewExamine);
OldExNext = (APTR)SetFunction(DOSBase, EXNEXT, NewExNext);
OldOpen = (APTR)SetFunction(DOSBase, OPEN, NewOpen);
OldClearMenuStrip = (APTR)SetFunction(IntuitionBase, CLEARMENUSTRIP, NewClearMenuStrip);
/* Remember setup data. */
IconPort -> Remove = RemoveIcon;
IconPort -> Segment = ((struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI)) -> cli_Module;
/* Make the port public. */
AddPort(&IconPort -> VanillaPort);
/* Make the Shell believe that `Icon' has
* already terminated.
*/
((struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI)) -> cli_Module = NULL;
return(TRUE);
}
/* Clear the port. */
FreeVec(IconPort);
}
return(FALSE);
}
/* Local2Upper(UBYTE c):
*
* Custom version of toupper, will also handle international
* characters.
*/
UBYTE
Local2Upper(UBYTE c)
{
return((UBYTE)((((c) >= 224 && (c) <= 254) || ((c) >= 'a' && (c) <= 'z')) ? (c) - 32 : c));
}
/* StrCmp(UBYTE *a,UBYTE *b):
*
* Custom version of strcmp, compares ignoring case.
*/
UBYTE
StrCmp(UBYTE *a,UBYTE *b)
{
for( ; Local2Upper(*a) == Local2Upper(*b) ; a++, b++)
{
if(!(*a))
return(0);
}
return((UBYTE)(Local2Upper(*a) - Local2Upper(*b)));
}
/* DeleteNode(struct Node *Node):
*
* Delete a node from a list and free the memory it
* occupies.
*/
VOID
DeleteNode(struct Node *Node)
{
Remove(Node);
FreeVec(Node);
}
/* CreateNode(UBYTE *Name):
*
* Create a node, allocate some extra space for the name
* and initialize it.
*/
struct Node *
CreateNode(UBYTE *Name)
{
struct Node *Node;
if(Node = (struct Node *)AllocVec(sizeof(struct Node) + strlen(Name) + 1,MEMF_PUBLIC|MEMF_CLEAR))
{
Node -> ln_Name = (UBYTE *)(Node + 1);
strcpy(Node -> ln_Name,Name);
}
return(Node);
}
/* Identify(UBYTE *Name):
*
* Heuristically identify the type of a file.
*/
UBYTE
Identify(UBYTE *Name)
{
ULONG *Buffer;
UBYTE Type = TYPE_FILE;
SHORT i,Len = strlen(Name);
/* Allocate a buffer for the first 400 bytes of the
* file.
*/
if(Buffer = (ULONG *)AllocVec(400,MEMF_PUBLIC))
{
BPTR File,Size;
/* Open the file. */
if(File = Open(Name,MODE_OLDFILE))
{
/* Read the first 400 bytes. */
if((Size = Read(File,Buffer,400)) >= sizeof(ULONG))
{
/* Examine the first longword. */
switch(Buffer[0])
{
case 0x03E7: Type = TYPE_OBJECT;
break;
case 0x03F3: Type = TYPE_EXECUTABLE;
break;
case 0x03FA: Type = TYPE_LIB;
break;
case 0xF7593647:Type = TYPE_TEXFONT;
break;
case 0xF7020183:Type = TYPE_TEXDVI;
break;
case 0xF7832020:Type = TYPE_GF;
break;
case 'FLIB': Type = TYPE_FLIB;
break;
case 'FORM': switch(Buffer[2])
{
case 'ILBM': Type = TYPE_ILBM;
break;
case 'ANIM': Type = TYPE_ANIM;
break;
case '8SVX': Type = TYPE_8SVX;
break;
case 'SMUS': Type = TYPE_SMUS;
break;
case 'FTXT': Type = TYPE_FTXT;
break;
case 'PREF': Type = TYPE_PREFS;
break;
case 'TERM': Type = TYPE_TERM;
break;
}
break;
case 'IMP!': Type = TYPE_IMPLODER;
break;
case 'PP20': Type = TYPE_POWERPACKER;
break;
case 'DMS!': Type = TYPE_DMS;
break;
case 'Warp': Type = TYPE_WARP;
break;
case 'ZOOM': Type = TYPE_ZOOM;
break;
case 0x504B0304:Type = TYPE_ZIP;
break;
case 'ZOO ': Type = TYPE_ZOO;
break;
case 'GIF8': Type = TYPE_GIF;
break;
default: break;
}
/* No match yet, see if it's an
* ASCII file.
*/
if(Type == TYPE_FILE)
{
UBYTE *CharBuffer = (UBYTE *)Buffer;
SHORT Count = 0;
for(i = 0 ; i < Size ; i++)
{
if(ValidTab[CharBuffer[i]])
Count++;
else
{
if(InvalidTab[CharBuffer[i]])
{
Count = 0;
break;
}
}
}
/* If more than 75% of the
* characters in the first
* 400 bytes are legal
* ASCII characters this
* file is supposed to be
* a text file.
*/
if(Count > 3 * (Size / 4))
Type = TYPE_TEXT;
}
/* Still no match, have another try... */
if(Type == TYPE_FILE)
{
if((Buffer[0] & 0xFFFF0000) == 0x1A080000)
Type = TYPE_ARC;
else
{
if((Buffer[0] & 0x0000FFFF) == 0x00002D6C && (Buffer[1] & 0xFF00FF00) == 0x68002D00)
Type = TYPE_LHARC;
else
{
switch(Buffer[0] & 0xFFFF0000)
{
case 0x434A0000: Type = TYPE_NEWMANX;
break;
case 0x414A0000: Type = TYPE_OLDMANX;
break;
case 0x636A0000: Type = TYPE_NEWMANXLIB;
break;
case 0x616A0000: Type = TYPE_OLDMANXLIB;
break;
case 0xF5000000: Type = TYPE_BASIC;
break;
default: break;
}
}
}
}
/* Take a look at the file name
* suffixes.
*/
switch(Type)
{
case TYPE_TEXT:
for(i = 0 ; i < sizeof(TextSuffix) / sizeof(struct Suffix) ; i++)
{
Size = strlen(TextSuffix[i] . Name);
if(Len >= Size)
{
if(!StrCmp(&Name[Len - Size],TextSuffix[i] . Name))
{
Type = TextSuffix[i] . Type;
break;
}
}
}
break;
case TYPE_EXECUTABLE:
for(i = 0 ; i < sizeof(ExecutableSuffix) / sizeof(struct Suffix) ; i++)
{
Size = strlen(ExecutableSuffix[i] . Name);
if(Len >= Size)
{
if(!StrCmp(&Name[Len - Size],ExecutableSuffix[i] . Name))
{
Type = ExecutableSuffix[i] . Type;
break;
}
}
}
break;
case TYPE_OBJECT:
if(Len >= 4)
{
if(!StrCmp(&Name[Len - 4],".LIB"))
Type = TYPE_LIB;
}
break;
default: break;
}
}
Close(File);
}
FreeVec(Buffer);
}
return(Type);
}
/* AddName(UBYTE *FileName,UBYTE Type):
*
* Add another name to the list of file names.
*/
VOID
AddName(UBYTE *FileName,UBYTE Type)
{
struct Node *Node;
UBYTE Name[108];
SHORT i;
BYTE HasInfo = FALSE;
/* Make sure that we will be able to handle the file type. */
if(StrCmp(FileName,".info") && StrCmp(FileName,"Disk.info") && FileName[strlen(FileName) - 1] != ':')
{
strcpy(Name,FileName);
/* Check if the file name has an `.info' suffix. */
for(i = strlen(Name) - 1; i >= 0; i--)
{
if(Name[i] == '.')
{
if(!StrCmp(&Name[i],".info"))
{
Name[i] = 0;
HasInfo = TRUE;
break;
}
}
}
ObtainSemaphore(&NameSemaphore);
if(HasInfo)
{
/* This is probably an icon, see if there's
* a file with this name. If there is,
* remove the node from the list.
*/
if(Node = (struct Node *)MyFindName(&NameList,Name))
DeleteNode(Node);
else
{
/* Add another icon to the list. */
if(Node = CreateNode(FileName))
{
Node -> ln_Type = TYPE_ICON;
AddTail(&NameList,Node);
}
}
}
else
{
strcat(Name,".info");
/* Look if there's already an icon in the
* list. If there is one, remove it.
*/
if(Node = (struct Node *)MyFindName(&NameList,Name))
DeleteNode(Node);
else
{
/* Add the file to the list. */
if(Node = CreateNode(FileName))
{
Node -> ln_Type = Type;
AddTail(&NameList,Node);
}
}
}
ReleaseSemaphore(&NameSemaphore);
}
}
/* NewExamine():
*
* Patched dos.library routine, stuffs all files encountered
* by Workbench scan into a list.
*/
LONG __saveds __asm
NewExamine(register __d1 BPTR FileLock,register __d2 struct FileInfoBlock *FileInfo)
{
/* Is it Workbench who's calling? */
if(!strcmp(SysBase -> ThisTask -> tc_Node . ln_Name,"Workbench"))
{
/* Are there still nodes in the scan list?
* If so, clear the list.
*/
if(NameList . lh_Head -> ln_Succ)
{
struct Node *Node,*NextNode;
ObtainSemaphore(&NameSemaphore);
Node = NameList . lh_Head;
while(Node -> ln_Succ)
{
NextNode = Node -> ln_Succ;
DeleteNode(Node);
Node = NextNode;
}
ReleaseSemaphore(&NameSemaphore);
ScanNode = NULL;
}
/* Jump back into original dos.library routine. */
if(MyExamine(FileLock,FileInfo))
{
/* If enabled identify the file type
* and add the file to the list.
*/
if(FakeScan)
{
if(StrCmp(FileInfo -> fib_FileName,".info") && StrCmp(FileInfo -> fib_FileName,"Disk.info") && FileInfo -> fib_FileName[strlen(FileInfo -> fib_FileName) - 1] != ':')
{
UBYTE Type = FileInfo -> fib_DirEntryType < 0 ? TYPE_FILE : TYPE_DIR;
if(Type == TYPE_FILE)
Type = Identify(FileInfo -> fib_FileName);
AddName(FileInfo -> fib_FileName,Type);
if(Type != TYPE_EXECUTABLE)
FileInfo -> fib_Protection |= FIBF_EXECUTE;
}
}
return(DOSTRUE);
}
else
return(DOSFALSE);
}
/* Jump into original routine. */
return(MyExamine(FileLock,FileInfo));
}
/* NewExNext():
*
* Patched dos.library routine, stuffs all files encountered
* by Workbench scan into a list.
*/
LONG __saveds __asm
NewExNext(register __d1 BPTR FileLock,register __d2 struct FileInfoBlock *FileInfo)
{
/* Is it Workbench who's calling? */
if(!strcmp(SysBase -> ThisTask -> tc_Node . ln_Name,"Workbench"))
{
/* If enabled identify the file type
* and add the file to the list.
*/
if(FakeScan)
{
/* If ScanNode is nonzero we are actually
* faking icons.
*/
if(ScanNode)
{
/* Scan the list for approriate files. */
while(ScanNode -> ln_Succ)
{
/* Are we able to produce and
* icon for this file?
*/
if(ScanNode -> ln_Type != TYPE_ICON && ScanNode -> ln_Type != TYPE_DIR && NameInfo[ScanNode -> ln_Type] . IsPresent)
{
/* Clear the contents of the FileInfoBlock. */
memset(FileInfo,0,sizeof(struct FileInfoBlock));
/* Set the entries to default values. */
FileInfo -> fib_DirEntryType = -1;
FileInfo -> fib_Size = 42;
FileInfo -> fib_NumBlocks = 1;
FileInfo -> fib_Protection = FIBF_EXECUTE;
/* Provide a simple date. */
DateStamp(&FileInfo -> fib_Date);
/* Produce and icon. */
SPrintf(FileInfo -> fib_FileName,"%s.info",ScanNode -> ln_Name);
ScanNode = ScanNode -> ln_Succ;
return(DOSTRUE);
}
ScanNode = ScanNode -> ln_Succ;
}
/* End of list reached. */
SetIoErr(ERROR_NO_MORE_ENTRIES);
return(DOSFALSE);
}
/* Jump into original dos.library routine. */
if(MyExNext(FileLock,FileInfo))
{
/* Identify file type and add it to the list. */
if(StrCmp(FileInfo -> fib_FileName,".info") && StrCmp(FileInfo -> fib_FileName,"Disk.info") && FileInfo -> fib_FileName[strlen(FileInfo -> fib_FileName) - 1] != ':')
{
UBYTE Type = FileInfo -> fib_DirEntryType < 0 ? TYPE_FILE : TYPE_DIR;
if(Type == TYPE_FILE)
Type = Identify(FileInfo -> fib_FileName);
AddName(FileInfo -> fib_FileName,Type);
if(Type != TYPE_EXECUTABLE)
FileInfo -> fib_Protection |= FIBF_EXECUTE;
}
return(DOSTRUE);
}
else
{
struct Node *Node;
UBYTE Buffer[40];
BPTR FileLock;
SHORT i;
/* We have just reached the end of list, there are no more
* directory entries. Now it's time to see if all icons
* are available and to determine the files to produce
* icons for.
*/
ObtainSemaphore(&NameSemaphore);
/* Clear the list entry flags. */
for(i = 0 ; i < sizeof(NameInfo) / sizeof(struct NameInfo) ; i++)
NameInfo[i] . IsPresent = -1;
Node = NameList . lh_Head;
/* Scan the name list. At this point there are only those
* files in the list which are not accompanied by an icon.
*/
while(Node -> ln_Succ)
{
if(NameInfo[Node -> ln_Type] . IsPresent == -1 && NameInfo[Node -> ln_Type] . Name)
{
SPrintf(Buffer,"ENV:sys/def_%s.info",NameInfo[Node -> ln_Type] . Name);
/* Is the default icon available? */
if(FileLock = Lock(Buffer,ACCESS_READ))
{
NameInfo[Node -> ln_Type] . IsPresent = TRUE;
ScanNode = NameList . lh_Head;
UnLock(FileLock);
}
else
NameInfo[Node -> ln_Type] . IsPresent = FALSE;
}
Node = Node -> ln_Succ;
}
/* If there is an icon available produce the first
* fake icon.
*/
if(ScanNode)
{
while(ScanNode -> ln_Succ)
{
if(ScanNode -> ln_Type != TYPE_ICON && ScanNode -> ln_Type != TYPE_DIR && NameInfo[ScanNode -> ln_Type] . IsPresent)
{
memset(FileInfo,0,sizeof(struct FileInfoBlock));
FileInfo -> fib_DirEntryType = -1;
FileInfo -> fib_Size = 42;
FileInfo -> fib_NumBlocks = 1;
FileInfo -> fib_Protection = FIBF_EXECUTE;
DateStamp(&FileInfo -> fib_Date);
SPrintf(FileInfo -> fib_FileName,"%s.info",ScanNode -> ln_Name);
ScanNode = ScanNode -> ln_Succ;
ReleaseSemaphore(&NameSemaphore);
return(DOSTRUE);
}
ScanNode = ScanNode -> ln_Succ;
}
}
ReleaseSemaphore(&NameSemaphore);
SetIoErr(ERROR_NO_MORE_ENTRIES);
return(DOSFALSE);
}
}
}
/* Jump into original routine. */
return(MyExNext(FileLock,FileInfo));
}
/* NewOpen():
*
* Patched dos.library routine, opens the fake icon files
* produced by the patched Examine/ExNext routines.
*/
BPTR __saveds __asm
NewOpen(register __d1 UBYTE *Name,register __d2 LONG Mode)
{
UBYTE Buffer[108];
/* Is it Workbench who's calling? */
if(!strcmp(SysBase -> ThisTask -> tc_Node . ln_Name,"Workbench"))
{
/* Is there a list to scan? */
if(ScanNode)
{
struct Node *Node;
SHORT i;
/* Extract the base file name. */
strcpy(Buffer,Name);
for(i = strlen(Buffer) ; i >= 0; i--)
{
if(!StrCmp(&Buffer[i],".info"))
{
Buffer[i] = 0;
break;
}
}
/* Try to find the approriate icon file. */
if(Node = (struct Node *)MyFindName(&NameList,Buffer))
{
/* Change the name of the icon file
* into the approriate default icon
* type.
*/
SPrintf(Buffer,"ENV:sys/def_%s.info",NameInfo[Node -> ln_Type] . Name);
Name = Buffer;
}
}
}
/* Jump into original routine. */
return(MyOpen(Name,Mode));
}
/* NewClearMenuStrip():
*
* Patched intuition.libary routine, checks the Workbench menu
* to determine whether we are to create fake icons or not.
*/
VOID __saveds __asm
NewClearMenuStrip(register __a0 struct Window *Window)
{
struct Menu *Menu;
struct MenuItem *MenuItem,*SubItem;
FakeScan = FALSE;
/* Is this a Workbench window? */
if(Window -> Flags & WFLG_WBENCHWINDOW)
{
Menu = Window -> MenuStrip;
/* Walk through the menus... */
while(Menu && !FakeScan)
{
MenuItem = Menu -> FirstItem;
/* Walk through the menu items... */
while(MenuItem && !FakeScan)
{
SubItem = MenuItem -> SubItem;
/* Walk through the sub items... */
while(SubItem && !FakeScan)
{
/* Sub item with item text? */
if(SubItem -> Flags & ITEMTEXT)
{
/* Is it the `All Files'
* subitem?
*/
if(!strcmp(((struct IntuiText *)SubItem -> ItemFill) -> IText,"All Files"))
{
/* See if it's
* checked.
*/
if(SubItem -> Flags & CHECKED)
FakeScan = TRUE;
else
FakeScan = FALSE;
}
}
SubItem = SubItem -> NextItem;
}
MenuItem = MenuItem -> NextItem;
}
Menu = Menu -> NextMenu;
}
}
/* Jump into original routine. */
MyClearMenuStrip(Window);
}